import {BasicType, createCheckers, ICheckerSuite} from 'ts-interface-checker';
import CustomSectionAPITI from './CustomSectionAPI-ti';
import FileParserAPITI from './FileParserAPI-ti';
import GristAPITI from './GristAPI-ti';
import GristTableTI from './GristTable-ti';
import ImportSourceAPITI from './ImportSourceAPI-ti';
import InternalImportSourceAPITI from './InternalImportSourceAPI-ti';
import RenderOptionsTI from './RenderOptions-ti';
import StorageAPITI from './StorageAPI-ti';
import WidgetAPITI from './WidgetAPI-ti';

/**
 * The ts-interface-checker type suites are all exported with the "TI" suffix.
 */
export {
  CustomSectionAPITI, FileParserAPITI, GristAPITI, GristTableTI, ImportSourceAPITI,
  InternalImportSourceAPITI, RenderOptionsTI, StorageAPITI, WidgetAPITI};

const allTypes = [
  CustomSectionAPITI, FileParserAPITI, GristAPITI, GristTableTI, ImportSourceAPITI,
  InternalImportSourceAPITI, RenderOptionsTI, StorageAPITI, WidgetAPITI,
];

// Ensure Buffer can be handled if mentioned in the interface descriptions, even if not supported
// in the current environment (i.e. browser).
if (typeof Buffer === 'undefined') {
  allTypes.push({Buffer: new BasicType((v) => false, "Buffer is not supported")});
}

function checkDuplicates(types: Array<{[key: string]: object}>) {
  const seen = new Set<string>();
  for (const t of types) {
    for (const key of Object.keys(t)) {
      if (seen.has(key)) { throw new Error(`TypeCheckers: Duplicate type name ${key}`); }
      seen.add(key);
      // Uncomment the line below to generate updated list of included types.
      // console.log(`'${key}' |`);
    }
  }
}

checkDuplicates(allTypes);

/**
 * We also create and export a global checker object that includes all of the types above.
 */
export const checkers = createCheckers(...allTypes) as (
  // The following Pick typecast ensures that Typescript can only use correct properties of the
  // checkers object (e.g. checkers.GristAPI will compile, but checkers.GristApi will not).
  // TODO: The restrictive type of ICheckerSuite should be generated automatically. (Currently
  // generated by commenting out console.log() in checkDuplicates() above.)
  Pick<ICheckerSuite,
  'CustomSectionAPI' | 'EditOptionsAPI' | 'ParseFileAPI' | 'ParseOptions' | 'ParseOptionSchema' |
  'FileSource' | 'ParseFileResult' | 'ComponentKind' | 'GristAPI' | 'GristDocAPI' | 'GristTable' |
  'GristTables' | 'GristColumn' | 'GristView' | 'ImportSourceAPI' | 'ImportProcessorAPI' | 'FileContent' |
  'FileListItem' | 'URL' | 'ImportSource' | 'InternalImportSourceAPI' | 'RenderTarget' |
  'RenderOptions' | 'Storage' | 'WidgetAPI'
  >);
